`timescale 1ns/1ps
`default_nettype none

/* NOTE:
* - 本模是图像存储、显示核心模块
* - 本模块用于跟灯饰系统对接，便于调试
*/

`define ENABLE_PIXEL_ADJUST

module led_display_top
    #(
    parameter   DW      = 96,
    parameter   DP      = 96
    )
    (
    // system signal
    input  wire         I_sclk,  // 125M
    input  wire         I_sdram_clk, // 150M
    input  wire         I_rst_n,
    
    //PHY模块接口
    input  wire         mac_flag,
    input  wire [7:0]   mac_data,
    input  wire [1:0]   mac_vendor,//0:无效包 1：UDP
    input  wire         mac_error,
    
    output reg          lock_enable,
    output wire         locked,
    
    output wire         O_frame_start,
    
    // key patter
    output wire         kp_busy,

    // time
    input  wire         I_time_1ms_sync,
    input  wire         I_time_1s_sync,
    // bus interface
    input  wire         I_bus_init_done,

    input  wire [3:0]       apb_sel              ,
    input  wire [31:0]      apb_addr             ,
    input  wire             apb_rw_en            ,
    input  wire [31:0]      apb_wdata            ,
    output reg  [31:0]      apb_rdata1           ,

    output wire         busy ,           //忙状态

    // self sync
    input  wire         I_self_sync,

    // led signal
    output wire         O_oe_out,
    output wire         O_load_out,
    output wire         O_deghost_ctrl,
    output wire [4:0]   O_scan_out,
    output wire         O_clock_out,
    output wire [DP-1:0] O_data_out,
    // sdram status
    output wire         O_sdram_ready,
    // sdram signals
    output wire         O_sdram_cke,    // CKE
    output wire         O_sdram_cs_n,   // CS#
    output wire         O_sdram_ras_n,  // RAS#
    output wire         O_sdram_cas_n,  // CAS#
    output wire         O_sdram_we_n,   // WE#
    output wire [1:0]   O_sdram_ba,     // BA
    output wire [10:0]  O_sdram_addr,   // A
    output wire [3:0]   O_sdram_dqm,    // DQM
    inout  tri  [31:0]  IO_sdram_dq     // DQ output
);
//------------------------Parameter----------------------
localparam
    DQ_BITS = 32, // width of data
    BA_BITS = 2,  // width of bank address
    RA_BITS = 11, // width of row address
    CA_BITS = 8;  // width of column address

localparam
    SYNC_MS = 18; // 内部同步信号周期ms
//------------------------Local signal-------------------
// config
wire [12:0] cfg_win_pos_x;          // x坐标，有符号
wire [11:0] cfg_win_pos_y;          // y坐标，有符号
wire [10:0] cfg_win_col_num;        // 带载列数（宽度）
wire [10:0] cfg_win_row_num;        // 带载行数（高度）
wire [7:0]  cfg_win_id;             // 屏幕id
wire [5:0]  cfg_color_sel;          // RGB选择
wire [2:0]  cfg_decode_type;        // 译码方式
wire        cfg_data_polarity;      // 数据极性
wire        cfg_oe_polarity;        // oe极性
wire [9:0]  cfg_scan_pixel;         // 一扫的像素数量（不包含虚点）
wire [9:0]  cfg_scan_length;        // 一扫的像素数量（包含虚点）
wire [5:0]  cfg_scan_max;           // 最大扫描id
wire [5:0]  cfg_port_max;           // 最大端口id
wire [3:0]  cfg_sector_count;       // 多开数量
wire [10:0] cfg_sector_width;       // 每个"多开区域"宽度
wire [9:0]  cfg_sector_height;      // 每个"多开区域"高度
wire [1:0]  cfg_write_rgb_mode;
wire [1:0]  cfg_scan_mode;
wire [7:0]  cfg_chip_type;          // 芯片类型
wire [1:0]  cfg_box_dir;            // 箱体方向
wire [1:0]  cfg_block_max;          // 列模式下最大分区id
wire [1:0]  cfg_col_loop;           // 列模式读取循环次数(数据组数/8,向上取整)
wire [7:0]  cfg_col_step;           // 列模式每次读地址间隔
wire [7:0]  cfg_vport_num;          // 虚拟数据组数
wire [31:0] cfg_vport_mask;         // 虚拟数据组中有效组标识
wire [15:0] cfg_decode_param0;      // 译码参数0
wire [15:0] cfg_decode_param1;      // 译码参数1
wire [15:0] cfg_deghost_ctrl_dly;   // 消影信号延迟
wire [15:0] cfg_deghost_ctrl_len;   // 消影信号长度
wire [7:0]  cfg_port_height;        // 每个port带载高度
wire [7:0]  cfg_clock_low;          // 时钟低电平时钟数
wire [7:0]  cfg_clock_cycle;        // 时钟整周期时钟数
wire [7:0]  cfg_clock_phase;        // 时钟相位
wire [7:0]  cfg_clock_phase_2;      // 时钟相位2
wire [7:0]  cfg_line_pos;           // 换行位置
wire [7:0]  cfg_load_width;         // load信号宽度 (>=2)
wire [15:0] cfg_chain_cycle;        // 串移时钟数
wire        cfg_fps_sync_en;        // 帧率同步使能
wire [15:0] cfg_min_chain;          // 最小串移周期数
wire [11:0] cfg_chain_num;          // 显示周期串移数
wire        cfg_color_restore;      // 色彩还原
wire [3:0]  cfg_gamma_bit;          // gamma bit数, 0 - 1bit, ..., 15 - 16bit
wire        cfg_gamma_incr;         // 低灰递增补偿
wire [7:0]  cfg_oe_pre_width;       // 切换非整周期时oe提前拉低宽度
wire        cfg_temp_adj_en;        // 全局色温调整
wire        cfg_color_adj_en;       // 全局色度调整
wire [15:0] cfg_temp_coe_r;         // 色温调整系数
wire [15:0] cfg_temp_coe_g;         // 色温调整系数
wire [15:0] cfg_temp_coe_b;         // 色温调整系数
wire [15:0] cfg_color_coe_r0;       // 全局色度调整系数
wire [15:0] cfg_color_coe_g0;       // 全局色度调整系数
wire [15:0] cfg_color_coe_b0;       // 全局色度调整系数
wire [15:0] cfg_color_coe_r1;       // 全局色度调整系数
wire [15:0] cfg_color_coe_g1;       // 全局色度调整系数
wire [15:0] cfg_color_coe_b1;       // 全局色度调整系数
wire [15:0] cfg_color_coe_r2;       // 全局色度调整系数
wire [15:0] cfg_color_coe_g2;       // 全局色度调整系数
wire [15:0] cfg_color_coe_b2;       // 全局色度调整系数
wire        cfg_black_on_lost;      // 丢失信号后黑屏
wire        cfg_pixel_adj_en;       // 逐点色度调整
wire        cfg_pixel_adj_mode;     // 逐点色度调整
wire [255:0]cfg_pwm_setting;        // pwm芯片设置
wire        cfg_gap_adj_en;         // 缝隙调整使能
wire [7:0]  cfg_module_width;       // 模组宽度
wire [7:0]  cfg_module_height;      // 模组高度
wire [5:0]  cfg_module_col;         // 模组列数
wire [15:0] cfg_gap_center;         // 模组中间调整系数
wire        cfg_input_enable;       // 输入使能
wire        cfg_output_enable;      // 输出使能
wire [3:0]  cfg_pattern_mode;       // pattern工作模式
wire [2:0]  cfg_pattern_rgb;        // pattern颜色
wire [7:0]  cfg_pattern_col;        // pattern当前列
wire [7:0]  cfg_pattern_row;        // pattern当前行
wire [7:0]  cfg_pattern_pos_x;      // pattern走行时x坐标
wire [10:0] cfg_pattern_width;      // pattern宽度
wire [10:0] cfg_pattern_height;     // pattern高度
wire [10:0] cfg_pattern_hblank;     // pattern行间隔时间
wire [10:0] cfg_pattern_vblank;     // pattern列间隔
wire        cfg_force_en;
wire [4:0]  cfg_force_bit;
wire [3:0]  cfg_hub_brd_type;       // G602使用的Hub板类型

// status
wire        status_key_en;
wire        status_pattern_en;
wire        frame_lost;

// sdram mux
wire        mux0_req;
wire        mux0_ack;
wire        mux0_irq;
wire        mux0_cs_n;
wire        mux0_ras_n;
wire        mux0_cas_n;
wire        mux0_we_n;
wire [1:0]  mux0_ba;
wire [10:0] mux0_addr;
wire [31:0] mux0_dq_out;
wire [31:0] mux0_dq_in;
wire        mux0_dq_oe;
wire [3:0]  mux0_dqm;
wire        mux1_req;
wire        mux1_ack;
wire        mux1_irq;
wire        mux1_cs_n;
wire        mux1_ras_n;
wire        mux1_cas_n;
wire        mux1_we_n;
wire [1:0]  mux1_ba;
wire [10:0] mux1_addr;
wire [31:0] mux1_dq_out;
wire [31:0] mux1_dq_in;
wire        mux1_dq_oe;
wire [3:0]  mux1_dqm;
wire        mux2_req;
wire        mux2_ack;
wire        mux2_irq;
wire        mux2_cs_n;
wire        mux2_ras_n;
wire        mux2_cas_n;
wire        mux2_we_n;
wire [1:0]  mux2_ba;
wire [10:0] mux2_addr;
wire [31:0] mux2_dq_out;
wire [31:0] mux2_dq_in;
wire        mux2_dq_oe;
wire [3:0]  mux2_dqm;
wire        mux3_req;
wire        mux3_ack;
wire        mux3_irq;
wire        mux3_cs_n;
wire        mux3_ras_n;
wire        mux3_cas_n;
wire        mux3_we_n;
wire [1:0]  mux3_ba;
wire [10:0] mux3_addr;
wire [31:0] mux3_dq_out;
wire [31:0] mux3_dq_in;
wire        mux3_dq_oe;
wire [3:0]  mux3_dqm;

wire        mux4_req;
wire        mux4_ack;
wire        mux4_irq;
wire        mux4_cs_n;
wire        mux4_ras_n;
wire        mux4_cas_n;
wire        mux4_we_n;
wire [1:0]  mux4_ba;
wire [10:0] mux4_addr;
wire [31:0] mux4_dq_out;
wire [31:0] mux4_dq_in;
wire        mux4_dq_oe;
wire [3:0]  mux4_dqm;


// row_addr_decoder
wire        decode_req;
wire [1:0]  decode_buf_sel;
wire [9:0]  decode_row;
wire [2:0]  decode_sector;
wire        decode_done;
wire [20:0] decode_addr;

// rgb_row_addr_decoder
wire        decode_rgb_req;     // 行地址译码请求
wire [1:0]  decode_rgb_buf_sel;  // SDRAM按帧分块选择
wire [9:0]  decode_rgb_row;     // 行号
wire [3:0]  decode_rgb_sector;   // 分区号
wire        decode_rgb_done;     // 译码完成
wire [20:0] decode_rgb_addr;    // 译码结果
wire [9:0]  decode_rgb_addr_in;
wire [9:0]  decode_rgb_addr_out;

// pixel coe
wire        coe_load_req;
wire [9:0]  coe_load_row;
wire        coe_load_busy;
wire        pixel_coe_ack;
wire [15:0] pixel_coe_r;
wire [15:0] pixel_coe_g;
wire [15:0] pixel_coe_b;

// gamma_table
wire        gamma_start;
wire [7:0]  gamma_data;
wire [15:0] gamma_result;

// gap info
wire        gap_coe_req;
wire [9:0]  gap_coe_row;
wire        gap_coe_busy;
wire        gap_coe_ack;
wire [15:0] gap_coe_val;

// cycle info
wire        cycle_info_rden;
wire [8:0]  cycle_info_addr;
wire [15:0] cycle_info_q;

// scan map
wire        scan_map_rden;
wire [5:0]  scan_map_addr;
wire [5:0]  scan_map_q;

// port map
wire        port_map_rden;
wire [7:0]  port_map_addr;
wire [4:0]  port_map_q;

// port map 2
wire        port_map_rden_2;
wire [7:0]  port_map_addr_2;
wire [15:0] port_map_q_2;

// column addr table
wire        col_addr_req;
wire [8:0]  col_addr_index;
wire [8:0]  col_addr_data;

// input frame
reg         frame_enable;
reg         frame_start;
wire        frame_end;
wire        row_end;
wire        burst_start;
wire        pixel_en;

// frame rate controller
wire        write_frame_req;
wire [1:0]  write_frame_id;
wire        read_frame_req;
wire [1:0]  read_frame_id;

wire [1:0]  read_frame_id_0;
wire [1:0]  write_frame_id_0;
// key_pattern
wire        kp_frame_start;
wire        kp_frame_end;
wire        kp_row_end;
wire        kp_burst_start;
wire [12:0] kp_burst_row;
wire [12:0] kp_burst_col;
wire        kp_pixel_en;
wire [7:0]  kp_pixel_data;

// pattern_gen
wire        pg_frame_start;
wire        pg_frame_end;
wire        pg_row_end;
wire        pg_burst_start;
wire [12:0] pg_burst_row;
wire [12:0] pg_burst_col;
wire        pg_pixel_en;
wire [7:0]  pg_pixel_data;

// global light
reg  [2:0]  time_cnt;
reg  [8:0]  ext_light;
reg  [8:0]  incr_light;
wire [1:0]  incr_step;
reg  [8:0]  final_light;
wire [15:0] light_adj_coe;

// output init
reg         init_done;
reg  [2:0]  frame_ready;
reg         output_enable;

// misc
wire        ext_lock_output;
wire        ext_black_screen;
wire        ext_self_sync;
reg  [12:0] win_pos_x;
reg  [11:0] win_pos_y;
wire        frame_sync;
wire        fps_sync_en;
reg  [4:0]  ms_cnt;
reg         internal_sync;

// sdram status
wire        sdram_ready_tmp;
reg  [1:0]  sdram_ready_sr;

wire        fake_frame_start;
wire        I_fake_frame_start;

wire frame_req;

// 显示设置包内容
wire        disp_set_pkg_received;
wire [7:0]  state;
wire [7:0]  state_2;
wire [7:0]  disp_contrast;
wire [7:0]  disp_light;


// input frame
wire         I_frame_start      ;
wire         I_frame_end        ;
wire         I_row_end          ;
wire         I_burst_start      ;
wire [12:0]  I_burst_row        ;
wire [12:0]  I_burst_col        ;
wire         I_pixel_en         ;
wire [7:0]   I_pixel_data       ;


reg         cfg_write;
reg         lock_write;
reg [31:0]  lock;
reg         ram_wr_rgb;

reg          ram_wren;
reg          req  ;
reg          rw   ;
reg  [23:0]  sdram_addr   ;     //请求sdram的地址
reg  [10:0]  rw_len     ;

wire [31:0] apb_rdata;
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        apb_rdata1 <= 'b0;
    else if ( apb_sel[1] && apb_addr[27:16] == 12'h100 )
        apb_rdata1 <= apb_rdata;
    else
        apb_rdata1 <= 'b0;
end

always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        cfg_write <= 1'b0;
    else if ( apb_sel[0] && apb_addr[27:16] == 12'h100 && apb_rw_en )
        cfg_write <= 1'b1;
    else
        cfg_write <= 1'b0;
end
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        lock_write <= 1'b0;
    else if ( apb_sel[0] && apb_addr[27:16] == 12'h500 && apb_rw_en )
        lock_write <= 1'b1;
    else
        lock_write <= 1'b0;
end

/******************************************************/
//lock 
/******************************************************/
always @(posedge I_sclk)begin
    if (lock_write)
    case (apb_addr[2])
        0: begin
            lock_enable <= (apb_wdata[7:0] == 'h3A);
            lock[31:24] <= apb_wdata[15:8];
            lock[23:16] <= apb_wdata[23:16];
            lock[15:8]  <= apb_wdata[31:24];
        end
        1: begin
            lock[7:0]   <= apb_wdata[7:0];
        end
    endcase
end

// key_pattern ram wr_en
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        ram_wr_rgb <= 1'b0;
    else if ( apb_sel[1] && apb_addr[27:16] == 12'h000 && apb_rw_en )
        ram_wr_rgb <= 1'b1;
    else
        ram_wr_rgb <= 1'b0;
end

/******************************************************/
//key_patter 在ahb   0xa900_0000
/******************************************************/
reg key_patter_wr;
reg key_out;
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        key_patter_wr <= 1'b0;
    else if (apb_sel[0] && apb_addr[27:16]==12'h900 && apb_rw_en)
        key_patter_wr <= 1'b1;
    else 
        key_patter_wr <= 1'b0;
end
always@(posedge I_sclk or negedge I_rst_n)begin
    if (!I_rst_n)
        key_out <= 0;
    else if (key_patter_wr && apb_addr[3:0] == 4'd0)
        key_out <= apb_wdata[0] ;
    else 
        key_out <= 0;
end


// sdram
always@(posedge I_sclk or negedge I_rst_n)begin
    if (I_rst_n == 0)
        ram_wren <= 0;
    else if ( apb_sel[1]  && apb_addr[27:16] == 12'h100 && apb_rw_en )
        ram_wren <= 1 ;
    else 
        ram_wren <= 0;
end

reg sdram_req_valid;
always@(posedge I_sclk or negedge I_rst_n)begin
    if (I_rst_n == 0)
        sdram_req_valid <= 0;
    else if (apb_sel[0]  && apb_addr[27:16] == 12'ha00 && apb_rw_en )
        sdram_req_valid <= 1'b1;
    else 
        sdram_req_valid <= 0;
end


always@(posedge I_sclk or negedge I_rst_n)begin
    if (I_rst_n == 0)
        req <= 0;
    else if (sdram_req_valid  && apb_addr[3:0] == 4'd0)
        req <= apb_wdata[0] ;
    else 
        req <= 0;
end

always@(posedge I_sclk or negedge I_rst_n)begin
    if (I_rst_n == 0)
        rw <= 0;
    else if (sdram_req_valid  && apb_addr[3:0] == 4'd4)
        rw <= apb_wdata[0] ;
end

always@(posedge I_sclk or negedge I_rst_n)begin
    if (I_rst_n == 0)
        sdram_addr <= 0;
    else if (sdram_req_valid && apb_addr[3:0] == 4'd8)
        sdram_addr <= apb_wdata[23:0] ;
end

always@(posedge I_sclk or negedge I_rst_n)begin
    if (I_rst_n == 0)
        rw_len <= 'd256;
    else if (sdram_req_valid  && apb_addr[3:0] == 4'd12)
        rw_len <= apb_wdata[10:0] ;
end




//**************************************************************
//          显示数据处理
//**************************************************************
//显示数据解码和截取
v8_data_rec_02 data_rec(
    .resetb                 (   I_rst_n             ),
    .sclk                   (   I_sclk              ),

    //PHY模块接口
    .mac_flag               (   mac_flag            ),
    .mac_data               (   mac_data            ),
    .mac_error              (   mac_error           ),
    .mac_vendor             (   mac_vendor          ),

    //显示设置数据输出
    .disp_set_pkg_received  (   disp_set_pkg_received       ),
    .state                  (   state                       ),
    .state_2                (   state_2                     ),
    .disp_contrast          (   disp_contrast               ),
    .disp_light             (   disp_light                  ),

    .lock_enable            (   lock_enable                 ),
    .lock                   (   lock                        ),
    .locked                 (   locked                      ),

    // to led_display_top
    .O_frame_start          (   I_frame_start               ),
    .O_frame_end            (   I_frame_end                 ),
    .O_burst_start          (   I_burst_start               ),
    .O_burst_row            (   I_burst_row                 ),
    .O_burst_col            (   I_burst_col                 ),
    .O_pixel_en             (   I_pixel_en                  ),
    .O_pixel_data           (   I_pixel_data                )
    
    );
assign O_frame_start = I_frame_start;

//------------------------Instantiation------------------
// cxy_deal_frame_start
cxy_deal_frame_start deal_frame_start(/*{{{*/
    .I_sclk             (I_sclk             ),
    .I_rst_n            (I_rst_n            ),
                                            
    .I_frame_start      (I_frame_start      ),
    .O_fake_frame_start (fake_frame_start   )
    );/*}}}*/


// rgb_pixel_save_top rgb_pixel_save_top (
    // // system signal
    // .I_sclk              ( I_sclk             ),  // 125M
    // .I_sdram_clk         ( I_sdram_clk        ),  // 150M
    // .I_rst_n             ( I_rst_n            ),
    // // config
    // .I_cfg_win_pos_x     ( cfg_win_pos_x      ),  // x坐标，有符号
    // .I_cfg_win_pos_y     ( cfg_win_pos_y      ),  // y坐标，有符号
    // .I_cfg_win_col_num   ( cfg_win_col_num    ),  // 带载列数（宽度）
    // .I_cfg_win_row_num   ( cfg_win_row_num    ),  // 带载行数（高度）
    // .I_cfg_box_dir       ( cfg_box_dir        ),
    // .I_cfg_sector_count  ( cfg_sector_count   ),  // 多开数量
    // .I_cfg_sector_width  ( cfg_sector_width   ),  // 每个"多开区域"宽度
    // .I_cfg_port_height   ( cfg_port_height    ),
    // // port map
    // .O_port_map_rden     ( port_map_rden_2    ),
    // .O_port_map_addr     ( port_map_addr_2    ),
    // .I_port_map_q        ( port_map_q_2       ),
    // // row addr decoder
    // .O_decode_req        ( decode_rgb_req     ),  // 行地址译码请求
    // .O_decode_buf_sel    ( decode_rgb_buf_sel ),  // SDRAM按帧分块选择
    // .O_decode_row        ( decode_rgb_row     ),  // 行号
    // .O_decode_sector     ( decode_rgb_sector  ),  // 分区号
    // .I_decode_done       ( decode_rgb_done    ),  // 译码完成
    // .I_decode_addr       ( decode_rgb_addr    ),  // 译码结果
    // .O_decode_col_addr   ( decode_rgb_addr_out),
    // .I_decode_col_addr   ( decode_rgb_addr_in ),
    // // input frame
    // .I_frame_start       ( frame_start        ),
    // .I_frame_id          ( write_frame_id_0   ),
    // .I_frame_end         ( frame_end          ),
    // .I_row_end           ( row_end            ),
    // .I_burst_start       ( burst_start        ),
    // .I_burst_row         ( pg_burst_row       ),
    // .I_burst_col         ( pg_burst_col       ),
    // .I_pixel_en          ( pixel_en           ),
    // .I_pixel_data        ( pg_pixel_data      ),
    // // sdram mux
    // .O_write_sdram_req   ( mux1_req           ),
    // .I_write_sdram_ack   ( mux1_ack           ),
    // .I_write_sdram_irq   ( mux1_irq           ),
    // .O_write_sdram_cs_n  ( mux1_cs_n          ),
    // .O_write_sdram_ras_n ( mux1_ras_n         ),
    // .O_write_sdram_cas_n ( mux1_cas_n         ),
    // .O_write_sdram_we_n  ( mux1_we_n          ),
    // .O_write_sdram_ba    ( mux1_ba            ),
    // .O_write_sdram_addr  ( mux1_addr          ),
    // .O_write_sdram_dq_out( mux1_dq_out        ),
    // .I_write_sdram_dq_in ( mux1_dq_in         ),
    // .O_write_sdram_dq_oe ( mux1_dq_oe         ),
    // .O_write_sdram_dqm   ( mux1_dqm           )

// );

// pixel_save_sdram_top save (/*{{{*/
    // .I_sclk               ( I_sclk ),
    // .I_sdram_clk          ( I_sdram_clk ),
    // .I_rst_n              ( I_rst_n ),
   
    // .I_cfg_light_adj_en   ( ~status_pattern_en & ~status_key_en ),
    // .I_cfg_temp_adj_en    ( cfg_temp_adj_en ),
    // .I_cfg_color_adj_en   ( cfg_color_adj_en ),
    // // .O_cfg_scan_cnt     ( cfg_gap_adj_en ),
    // .I_cfg_pixel_adj_en   ( cfg_pixel_adj_en ),
    // .I_cfg_pixel_adj_mode (cfg_pixel_adj_mode),
    // .I_cfg_temp_coe_r     ( cfg_temp_coe_r ),
    // .I_cfg_temp_coe_g     ( cfg_temp_coe_g ),
    // .I_cfg_temp_coe_b     ( cfg_temp_coe_b ),
    // .I_cfg_light_coe      ( light_adj_coe ),
    // .I_cfg_color_coe_r0   ( cfg_color_coe_r0 ),
    // .I_cfg_color_coe_g0   ( cfg_color_coe_g0 ),
    // .I_cfg_color_coe_b0   ( cfg_color_coe_b0 ),
    // .I_cfg_color_coe_r1   ( cfg_color_coe_r1 ),
    // .I_cfg_color_coe_g1   ( cfg_color_coe_g1 ),
    // .I_cfg_color_coe_b1   ( cfg_color_coe_b1 ),
    // .I_cfg_color_coe_r2   ( cfg_color_coe_r2 ),
    // .I_cfg_color_coe_g2   ( cfg_color_coe_g2 ),
    // .I_cfg_color_coe_b2   ( cfg_color_coe_b2 ),
    // .I_cfg_contrast_en    ( ~status_pattern_en & ~status_key_en ),
    // .I_cfg_contrast_coe   ( disp_contrast ),
    
    // .I_cfg_scan_mode      ( cfg_scan_mode ),
    // .I_cfg_box_dir        ( cfg_box_dir ),
    // .I_cfg_col_loop       ( cfg_col_loop ),
    // .I_cfg_col_step       ( cfg_col_step ),
    // .I_cfg_port_height    ( cfg_port_height  ),
    // .I_cfg_block_max      ( cfg_block_max ),
    
    // .I_cfg_scan_length    (cfg_scan_length),
    // .I_cfg_port_max       (cfg_port_max),
    // .I_cfg_scan_max       (cfg_scan_max), 
    // .I_cfg_sector_count   ( cfg_sector_count ),
    // .I_cfg_sector_width   ( cfg_sector_width ),
    // .I_cfg_sector_height  (cfg_sector_height ),
    // .I_cfg_win_col_num    ( cfg_win_col_num    ),  // 带载列数（宽度）
    // .I_cfg_win_row_num    ( cfg_win_row_num    ),  // 带载行数（高度）
    
    // .O_gamma_start        ( gamma_start ),
    // .O_gamma_data         ( gamma_data ),
    // .I_gamma_result       ( gamma_result ),
    // .O_gap_coe_req        ( gap_coe_req ),
    // .O_gap_coe_row        ( gap_coe_row ),
    // .I_gap_coe_busy       ( gap_coe_busy ),
    // .O_gap_coe_ack        ( gap_coe_ack ),
    // .I_gap_coe_val        ( gap_coe_val ),
    
    // .I_frame_start        ( frame_start ),//frame_req
    // .I_frame_id           ( write_frame_id ),
    // .frame_req            ( read_frame_req),//frame_start
    // .frist_frame          ( read_frame_id_0[1:0]),

    // .O_read_sdram_req     ( mux3_req ),
    // .I_read_sdram_ack     ( mux3_ack ),
    // .I_read_sdram_irq     ( mux3_irq ),
    // .O_read_sdram_cs_n    ( mux3_cs_n ),
    // .O_read_sdram_ras_n   ( mux3_ras_n ),
    // .O_read_sdram_cas_n   ( mux3_cas_n ),
    // .O_read_sdram_we_n    ( mux3_we_n ),
    // .O_read_sdram_ba      ( mux3_ba ),
    // .O_read_sdram_addr    ( mux3_addr ),
    // .O_read_sdram_dq_out  ( mux3_dq_out ),
    // .I_read_sdram_dq_in   ( mux3_dq_in ),
    // .O_read_sdram_dq_oe   ( mux3_dq_oe ),
    // .O_read_sdram_dqm     ( mux3_dqm ),
    // /*}}}*/
    // .O_write_sdram_req    ( mux2_req ),
    // .I_write_sdram_ack    ( mux2_ack ),
    // .I_write_sdram_irq    ( mux2_irq ),
    // .O_write_sdram_cs_n   ( mux2_cs_n ),
    // .O_write_sdram_ras_n  ( mux2_ras_n ),
    // .O_write_sdram_cas_n  ( mux2_cas_n ),
    // .O_write_sdram_we_n   ( mux2_we_n ),
    // .O_write_sdram_ba     ( mux2_ba ),
    // .O_write_sdram_addr   ( mux2_addr ),
    // .O_write_sdram_dq_out ( mux2_dq_out ),
    // .I_write_sdram_dq_in  ( mux2_dq_in ),
    // .O_write_sdram_dq_oe  ( mux2_dq_oe ),
    // .O_write_sdram_dqm    ( mux2_dqm )
// );/*}}}*/

// // pixel_display_top
// pixel_display_top /*{{{*/
    // #(
    // .DW                     (DW     ),
    // .DP                     (DP     )
    // )
  // disp(
    // .I_sclk                 ( I_sclk ),
    // .I_sdram_clk            ( I_sdram_clk ),
    // .I_rst_n                ( I_rst_n ),
    // .I_fake_frame_start     ( I_fake_frame_start ),
    // .I_frame_sync           ( frame_sync ),
    // .I_ext_lock_output      ( ext_lock_output ),
    // .I_ext_black_screen     ( ext_black_screen ),
    // .I_cfg_output_enable    ( output_enable ),
    // .I_cfg_scan_mode        ( cfg_scan_mode ),
    // .I_cfg_clock_low        ( cfg_clock_low ),
    // .I_cfg_clock_cycle      ( cfg_clock_cycle ),
    // .I_cfg_clock_phase      ( cfg_clock_phase ),
    // .I_cfg_clock_phase_2    ( cfg_clock_phase_2 ),
    // .I_cfg_data_polarity    ( cfg_data_polarity ),
    // .I_cfg_scan_pixel       ( cfg_scan_pixel ),
    // .I_cfg_scan_length      ( cfg_scan_length ),
    // .I_cfg_scan_max         ( cfg_scan_max ),
    // .I_cfg_port_max         ( cfg_port_max ),
    // .I_cfg_line_pos         ( cfg_line_pos ),
    // .I_cfg_load_width       ( cfg_load_width ),
    // .I_cfg_oe_pre_width     ( cfg_oe_pre_width ),
    // .I_cfg_oe_polarity      ( cfg_oe_polarity ),
    // .I_cfg_chain_cycle      ( cfg_chain_cycle ),
    // .I_cfg_fps_sync_en      ( ~status_pattern_en & fps_sync_en ),
    // .I_cfg_min_chain        ( cfg_min_chain ),
    // .I_cfg_chain_num        ( cfg_chain_num ),
    // .I_cfg_color_sel        ( cfg_color_sel ),
    // .I_cfg_box_dir          ( cfg_box_dir ),
    // .I_cfg_vport_num        ( cfg_vport_num ),
    // .I_cfg_vport_mask       ( cfg_vport_mask ),
    // .I_cfg_decode_param0    ( cfg_decode_param0 ),
    // .I_cfg_decode_param1    ( cfg_decode_param1 ),
    // .I_cfg_deghost_ctrl_dly ( cfg_deghost_ctrl_dly ),
    // .I_cfg_deghost_ctrl_len ( cfg_deghost_ctrl_len ),
    // .I_cfg_decode_type      ( cfg_decode_type ),
    // .I_cfg_chip_type        ( cfg_chip_type ),
    // .I_cfg_pwm_setting      ( cfg_pwm_setting ),
    // .I_cfg_force_en         ( cfg_force_en ),
    // .I_cfg_force_bit        ( cfg_force_bit ),
    // .I_cfg_hub_brd_type     ( cfg_hub_brd_type ),
    // .I_cfg_gamma_bit        ( cfg_gamma_bit ),
    // .O_cycle_info_rden      ( cycle_info_rden ),
    // .O_cycle_info_addr      ( cycle_info_addr ),
    // .I_cycle_info_q         ( cycle_info_q ),
    // .O_scan_map_rden        ( scan_map_rden ),
    // .O_scan_map_addr        ( scan_map_addr ),
    // .I_scan_map_q           ( scan_map_q ),
    // .O_port_map_rden        ( port_map_rden ),
    // .O_port_map_addr        ( port_map_addr ),
    // .I_port_map_q           ( port_map_q ),
    // .O_col_addr_req         ( col_addr_req ),
    // .O_col_addr_index       ( col_addr_index ),
    // .I_col_addr_data        ( col_addr_data ),
    // .O_frame_req            ( read_frame_req ),
    // .I_frame_id             ( read_frame_id ),
    // .I_sdram_ready          ( O_sdram_ready ),
    // .O_read_sdram_req       ( mux0_req ),
    // .I_read_sdram_ack       ( mux0_ack ),
    // .O_read_sdram_cs_n      ( mux0_cs_n ),
    // .O_read_sdram_ras_n     ( mux0_ras_n ),
    // .O_read_sdram_cas_n     ( mux0_cas_n ),
    // .O_read_sdram_we_n      ( mux0_we_n ),
    // .O_read_sdram_ba        ( mux0_ba ),
    // .O_read_sdram_addr      ( mux0_addr ),
    // .O_read_sdram_dq_out    ( mux0_dq_out ),
    // .I_read_sdram_dq_in     ( mux0_dq_in ),
    // .O_read_sdram_dq_oe     ( mux0_dq_oe ),
    // .O_read_sdram_dqm       ( mux0_dqm ),
    // .O_oe_out               ( O_oe_out ),
    // .O_load_out             ( O_load_out ),
    // .O_deghost_ctrl         ( O_deghost_ctrl ),
    // .O_scan_out             ( O_scan_out ),
    // .O_clock_out            ( O_clock_out ),
    // .O_data_out             ( O_data_out )
// );/*}}}*/

// sdram_mux
sdram_mux #(/*{{{*/
    .DQ_BITS       ( DQ_BITS ),
    .BA_BITS       ( BA_BITS ),
    .RA_BITS       ( RA_BITS ),
    .CA_BITS       ( CA_BITS )
) mux (
    .I_sclk        ( I_sdram_clk ),
    .I_rst_n       ( I_rst_n ),
    .O_sdram_ready ( sdram_ready_tmp ),
    .I_mux0_req    ( 'd0/*mux0_req*/ ),
    .O_mux0_ack    ( mux0_ack ),
    .O_mux0_irq    ( mux0_irq ),
    .I_mux0_cs_n   ( mux0_cs_n ),
    .I_mux0_ras_n  ( mux0_ras_n ),
    .I_mux0_cas_n  ( mux0_cas_n ),
    .I_mux0_we_n   ( mux0_we_n ),
    .I_mux0_ba     ( mux0_ba ),
    .I_mux0_addr   ( mux0_addr ),
    .I_mux0_dq_out ( mux0_dq_out ),
    .O_mux0_dq_in  ( mux0_dq_in ),
    .I_mux0_dq_oe  ( mux0_dq_oe ),
    .I_mux0_dqm    ( mux0_dqm ),
    .I_mux1_req    ( 'd0/*mux1_req*/ ),
    .O_mux1_ack    ( mux1_ack ),
    .O_mux1_irq    ( mux1_irq ),
    .I_mux1_cs_n   ( mux1_cs_n ),
    .I_mux1_ras_n  ( mux1_ras_n ),
    .I_mux1_cas_n  ( mux1_cas_n ),
    .I_mux1_we_n   ( mux1_we_n ),
    .I_mux1_ba     ( mux1_ba ),
    .I_mux1_addr   ( mux1_addr ),
    .I_mux1_dq_out ( mux1_dq_out ),
    .O_mux1_dq_in  ( mux1_dq_in ),
    .I_mux1_dq_oe  ( mux1_dq_oe ),
    .I_mux1_dqm    ( mux1_dqm ),
    .I_mux2_req    ( 'd0/*mux2_req*/ ),
    .O_mux2_ack    ( mux2_ack ),
    .O_mux2_irq    ( mux2_irq ),
    .I_mux2_cs_n   ( mux2_cs_n ),
    .I_mux2_ras_n  ( mux2_ras_n ),
    .I_mux2_cas_n  ( mux2_cas_n ),
    .I_mux2_we_n   ( mux2_we_n ),
    .I_mux2_ba     ( mux2_ba ),
    .I_mux2_addr   ( mux2_addr ),
    .I_mux2_dq_out ( mux2_dq_out ),
    .O_mux2_dq_in  ( mux2_dq_in ),
    .I_mux2_dq_oe  ( mux2_dq_oe ),
    .I_mux2_dqm    ( mux2_dqm ),
    .I_mux3_req    ( 'd0/*ux3_req*/ ),
    .O_mux3_ack    ( mux3_ack ),
    .O_mux3_irq    ( mux3_irq ),
    .I_mux3_cs_n   ( mux3_cs_n ),
    .I_mux3_ras_n  ( mux3_ras_n ),
    .I_mux3_cas_n  ( mux3_cas_n ),
    .I_mux3_we_n   ( mux3_we_n ),
    .I_mux3_ba     ( mux3_ba ),
    .I_mux3_addr   ( mux3_addr ),
    .I_mux3_dq_out ( mux3_dq_out ),
    .O_mux3_dq_in  ( mux3_dq_in ),
    .I_mux3_dq_oe  ( mux3_dq_oe ),
    .I_mux3_dqm    ( mux3_dqm ),

    .I_mux4_req    ( mux4_req ),
    .O_mux4_ack    ( mux4_ack ),
    .O_mux4_irq    ( mux4_irq ),
    .I_mux4_cs_n   ( mux4_cs_n ),
    .I_mux4_ras_n  ( mux4_ras_n ),
    .I_mux4_cas_n  ( mux4_cas_n ),
    .I_mux4_we_n   ( mux4_we_n ),
    .I_mux4_ba     ( mux4_ba ),
    .I_mux4_addr   ( mux4_addr ),
    .I_mux4_dq_out ( mux4_dq_out ),
    .O_mux4_dq_in  ( mux4_dq_in ),
    .I_mux4_dq_oe  ( mux4_dq_oe ),
    .I_mux4_dqm    ( mux4_dqm ),
    .O_sdram_cke   ( O_sdram_cke ),
    .O_sdram_cs_n  ( O_sdram_cs_n ),
    .O_sdram_ras_n ( O_sdram_ras_n ),
    .O_sdram_cas_n ( O_sdram_cas_n ),
    .O_sdram_we_n  ( O_sdram_we_n ),
    .O_sdram_ba    ( O_sdram_ba ),
    .O_sdram_addr  ( O_sdram_addr ),
    .O_sdram_dqm   ( O_sdram_dqm ),
    .IO_sdram_dq   ( IO_sdram_dq )
);/*}}}*/

//第一次SDRAM 的读写
frame_rate_controller frc_0 (/*{{{*/
    .I_sclk  ( I_sclk ),
    .I_rst_n ( I_rst_n ),
    .I_wrreq ( frame_start/*write_frame_req*/ ),
    .O_wrsel ( write_frame_id_0 ),
    .I_rdreq ( read_frame_req/*write_frame_req*/ ),
    .O_rdsel ( read_frame_id_0 )
);/*}}}*/

//第二次SDRAM的读写
// frame_rate_controller
frame_rate_controller frc_1 (/*{{{*/
    .I_sclk  ( I_sclk ),
    .I_rst_n ( I_rst_n ),
    .I_wrreq ( read_frame_req/*write_frame_req*/ ),
    .O_wrsel ( write_frame_id ),
    .I_rdreq ( read_frame_req ),
    .O_rdsel ( read_frame_id )
);/*}}}*/

// led_display_config
led_display_config cfg (/*{{{*/
    .I_sclk                 ( I_sclk ),
    .I_rst_n                ( I_rst_n ),
    .I_bus_init_done        ( I_bus_init_done ),
    .I_bus_write            ( cfg_write ),
    .I_bus_read             ( 1'b0           ),
    .I_bus_addr             ( apb_addr[15:0] ),
    .I_bus_wdata            ( apb_wdata[7:0] ),
    .O_bus_rdata            (                ),
    .O_cfg_win_pos_x        ( cfg_win_pos_x ),
    .O_cfg_win_pos_y        ( cfg_win_pos_y ),
    .O_cfg_win_col_num      ( cfg_win_col_num ),
    .O_cfg_win_row_num      ( cfg_win_row_num ),
    .O_cfg_win_id           ( cfg_win_id ),
    .O_cfg_color_sel        ( cfg_color_sel ),
    .O_cfg_decode_type      ( cfg_decode_type ),
    .O_cfg_data_polarity    ( cfg_data_polarity ),
    .O_cfg_oe_polarity      ( cfg_oe_polarity ),
    .O_cfg_scan_pixel       ( cfg_scan_pixel ),
    .O_cfg_scan_length      ( cfg_scan_length ),
    .O_cfg_scan_max         ( cfg_scan_max ),
    .O_cfg_port_max         ( cfg_port_max ),
    .O_cfg_sector_count     ( cfg_sector_count ),
    .O_cfg_sector_width     ( cfg_sector_width ),
    .O_cfg_sector_height    ( cfg_sector_height ),
    .O_cfg_scan_mode        ( cfg_scan_mode ),
    .O_cfg_chip_type        ( cfg_chip_type ),
    .O_cfg_box_dir          ( cfg_box_dir ),
    .O_cfg_block_max        ( cfg_block_max ),
    .O_cfg_col_loop         ( cfg_col_loop ),
    .O_cfg_col_step         ( cfg_col_step ),
    .O_cfg_vport_num        ( cfg_vport_num ),
    .O_cfg_vport_mask       ( cfg_vport_mask ),
    .O_cfg_decode_param0    ( cfg_decode_param0 ),
    .O_cfg_decode_param1    ( cfg_decode_param1 ),
    .O_cfg_deghost_ctrl_dly ( cfg_deghost_ctrl_dly ),
    .O_cfg_deghost_ctrl_len ( cfg_deghost_ctrl_len ),
    .O_cfg_port_height      ( cfg_port_height ),
    .O_cfg_clock_low        ( cfg_clock_low ),
    .O_cfg_clock_cycle      ( cfg_clock_cycle ),
    .O_cfg_clock_phase      ( cfg_clock_phase ),
    .O_cfg_clock_phase_2    ( cfg_clock_phase_2 ),
    .O_cfg_line_pos         ( cfg_line_pos ),
    .O_cfg_load_width       ( cfg_load_width ),
    .O_cfg_oe_pre_width     ( cfg_oe_pre_width ),
    .O_cfg_chain_cycle      ( cfg_chain_cycle ),
    .O_cfg_fps_sync_en      ( cfg_fps_sync_en ),
    .O_cfg_min_chain        ( cfg_min_chain ),
    .O_cfg_chain_num        ( cfg_chain_num ),
    .O_cfg_color_restore    ( cfg_color_restore ),
    .O_cfg_gamma_bit        ( cfg_gamma_bit ),
    .O_cfg_gamma_incr       ( cfg_gamma_incr ),
    .O_cfg_temp_adj_en      ( cfg_temp_adj_en ),
    .O_cfg_color_adj_en     ( cfg_color_adj_en ),
    .O_cfg_temp_coe_r       ( cfg_temp_coe_r ),
    .O_cfg_temp_coe_g       ( cfg_temp_coe_g ),
    .O_cfg_temp_coe_b       ( cfg_temp_coe_b ),
    .O_cfg_color_coe_r0     ( cfg_color_coe_r0 ),
    .O_cfg_color_coe_g0     ( cfg_color_coe_g0 ),
    .O_cfg_color_coe_b0     ( cfg_color_coe_b0 ),
    .O_cfg_color_coe_r1     ( cfg_color_coe_r1 ),
    .O_cfg_color_coe_g1     ( cfg_color_coe_g1 ),
    .O_cfg_color_coe_b1     ( cfg_color_coe_b1 ),
    .O_cfg_color_coe_r2     ( cfg_color_coe_r2 ),
    .O_cfg_color_coe_g2     ( cfg_color_coe_g2 ),
    .O_cfg_color_coe_b2     ( cfg_color_coe_b2 ),
    .O_cfg_black_on_lost    ( cfg_black_on_lost ),
    .O_cfg_pixel_adj_en     ( cfg_pixel_adj_en ),
    .O_cfg_pixel_adj_mode   ( cfg_pixel_adj_mode ),
    .O_cfg_pwm_setting      ( cfg_pwm_setting ),
    .O_cfg_gap_adj_en       ( cfg_gap_adj_en ),
    .O_cfg_module_width     ( cfg_module_width ),
    .O_cfg_module_height    ( cfg_module_height ),
    .O_cfg_module_col       ( cfg_module_col ),
    .O_cfg_gap_center       ( cfg_gap_center ),
    .O_cfg_input_enable     ( cfg_input_enable ),
    .O_cfg_output_enable    ( cfg_output_enable ),
    .O_cfg_pattern_mode     ( cfg_pattern_mode ),
    .O_cfg_pattern_rgb      ( cfg_pattern_rgb ),
    .O_cfg_pattern_col      ( cfg_pattern_col ),
    .O_cfg_pattern_row      ( cfg_pattern_row ),
    .O_cfg_pattern_pos_x    ( cfg_pattern_pos_x ),
    .O_cfg_pattern_width    ( cfg_pattern_width ),
    .O_cfg_pattern_height   ( cfg_pattern_height ),
    .O_cfg_pattern_hblank   ( cfg_pattern_hblank ),
    .O_cfg_pattern_vblank   ( cfg_pattern_vblank ),
    .O_cfg_force_en         ( cfg_force_en ),
    .O_cfg_force_bit        ( cfg_force_bit ),
    .O_cfg_hub_brd_type     ( cfg_hub_brd_type ),
    .I_gamma_start          ( gamma_start ),
    .I_gamma_data           ( gamma_data ),
    .O_gamma_result         ( gamma_result ),
    .I_gap_coe_req          ( gap_coe_req ),
    .I_gap_coe_row          ( gap_coe_row ),
    .O_gap_coe_busy         ( gap_coe_busy ),
    .I_gap_coe_ack          ( gap_coe_ack ),
    .O_gap_coe_val          ( gap_coe_val ),
    
    .I_rgb_decode_req       ( decode_rgb_req ),     // 行地址译码请求
    .I_rgb_decode_buf_sel   ( decode_rgb_buf_sel ), // SDRAM按帧分块选择
    .I_rgb_decode_row       ( decode_rgb_row ),     // 行号
    .I_rgb_decode_sector    ( decode_rgb_sector),  // 分区号
    .O_rgb_decode_done      ( decode_rgb_done ),    // 译码完成
    .O_rgb_decode_addr      ( decode_rgb_addr ),    // 译码结果
    .O_rgb_decode_col_addr  ( decode_rgb_addr_in[9:0] ),
    .I_rgb_decode_col_addr  ( decode_rgb_addr_out  ),
    
    .I_cycle_info_rden      ( cycle_info_rden ),
    .I_cycle_info_addr      ( cycle_info_addr ),
    .O_cycle_info_q         ( cycle_info_q ),
    .I_scan_map_rden        ( scan_map_rden ),
    .I_scan_map_addr        ( scan_map_addr ),
    .O_scan_map_q           ( scan_map_q ),
    .I_port_map_rden        ( port_map_rden ),
    .I_port_map_addr        ( port_map_addr ),
    .O_port_map_q           ( port_map_q ),
    .I_port_map_rden_2      ( port_map_rden_2 ),
    .I_port_map_addr_2      ( port_map_addr_2 ),
    .O_port_map_q_2         ( port_map_q_2 ),
    .I_col_addr_req         ( col_addr_req ),
    .I_col_addr_index       ( col_addr_index ),
    .O_col_addr_data        ( col_addr_data )
);/*}}}*/

// key_pattern
key_pattern kp (/*{{{*/
    .I_sclk              ( I_sclk ),
    .I_rst_n             ( I_rst_n ),
    .I_key_in            ( key_out ),

    .ram_waddr_rgb       ( apb_addr[9:0]   ),
    .ram_wdata_rgb       ( apb_wdata[31:0] ),
    .ram_wr_rgb          ( ram_wr_rgb ),

    .I_time_1ms_sync     ( I_time_1ms_sync ),
    .I_cfg_win_col_num   ( cfg_win_col_num ),
    .I_cfg_win_row_num   ( cfg_win_row_num ),
    .I_cfg_black_on_lost ( cfg_black_on_lost ),
    .O_status_key_en     ( status_key_en ),
    .O_frame_lost        ( frame_lost ),
    .I_frame_start       ( I_frame_start ),
    .I_frame_end         ( I_frame_end ),
    .I_row_end           ( I_row_end ),
    .I_burst_start       ( I_burst_start ),
    .I_burst_row         ( I_burst_row ),
    .I_burst_col         ( I_burst_col ),
    .I_pixel_en          ( I_pixel_en ),
    .I_pixel_data        ( I_pixel_data ),
    .O_frame_start       ( kp_frame_start ),
    .O_frame_end         ( kp_frame_end ),
    .O_row_end           ( kp_row_end ),
    .O_burst_start       ( kp_burst_start ),
    .O_burst_row         ( kp_burst_row ),
    .O_burst_col         ( kp_burst_col ),
    .O_pixel_en          ( kp_pixel_en ),
    .O_pixel_data        ( kp_pixel_data ),
    .kp_busy             ( kp_busy       )
);/*}}}*/

// pattern_gen
pattern_gen pg (/*{{{*/
    .I_sclk               ( I_sclk ),
    .I_rst_n              ( I_rst_n ),
    .I_cfg_pattern_mode   ( cfg_pattern_mode ),
    .I_cfg_pattern_rgb    ( cfg_pattern_rgb ),
    .I_cfg_pattern_col    ( cfg_pattern_col ),
    .I_cfg_pattern_row    ( cfg_pattern_row ),
    .I_cfg_pattern_pos_x  ( cfg_pattern_pos_x ),
    .I_cfg_pattern_width  ( cfg_pattern_width ),
    .I_cfg_pattern_height ( cfg_pattern_height ),
    .I_cfg_pattern_hblank ( cfg_pattern_hblank ),
    .I_cfg_pattern_vblank ( cfg_pattern_vblank ),
    .O_status_pattern_en  ( status_pattern_en ),
    .I_frame_start        ( kp_frame_start ),
    .I_frame_end          ( kp_frame_end ),
    .I_row_end            ( kp_row_end ),
    .I_burst_start        ( kp_burst_start ),
    .I_burst_row          ( kp_burst_row ),
    .I_burst_col          ( kp_burst_col ),
    .I_pixel_en           ( kp_pixel_en ),
    .I_pixel_data         ( kp_pixel_data ),
    .O_frame_start        ( pg_frame_start ),
    .O_frame_end          ( pg_frame_end ),
    .O_row_end            ( pg_row_end ),
    .O_burst_start        ( pg_burst_start ),
    .O_burst_row          ( pg_burst_row ),
    .O_burst_col          ( pg_burst_col ),
    .O_pixel_en           ( pg_pixel_en ),
    .O_pixel_data         ( pg_pixel_data )
);/*}}}*/

`ifdef ENABLE_PIXEL_ADJUST
// coe_writer
coe_writer coe_wr (/*{{{*/
    .I_sclk        ( I_sclk ),
    .I_sdram_clk   ( I_sdram_clk ),
    .I_rst_n       ( I_rst_n ),

     // ram 缓存
    .I_ram_addr     (apb_addr[9:0]),
    .I_ram_data_w   (apb_wdata[31:0]),
    .O_ram_data_r   (apb_rdata[31:0]),
    .I_ram_wren     (ram_wren),

    //request
    .I_req         (req     ),
    .I_rw          (rw     ),             //写请求为1，读请求为0
    .O_busy        (busy    ),           //忙状态
    .I_sdram_addr  (sdram_addr   ),     //请求sdram的地址
    .I_rw_len      ( rw_len        ),
    
    .O_mux_req     ( mux4_req      ),
    .I_mux_ack     ( mux4_ack      ),
    .I_mux_irq     ( mux4_irq      ),
    .O_mux_cs_n    ( mux4_cs_n     ),
    .O_mux_ras_n   ( mux4_ras_n    ),
    .O_mux_cas_n   ( mux4_cas_n    ),
    .O_mux_we_n    ( mux4_we_n     ),
    .O_mux_ba      ( mux4_ba       ),
    .O_mux_addr    ( mux4_addr     ),
    .O_mux_dq_out  ( mux4_dq_out   ),
    .I_mux_dq_in   ( mux4_dq_in    ),
    .O_mux_dq_oe   ( mux4_dq_oe    ),
    .O_mux_dqm     ( mux4_dqm      )
);/*}}}*/
`else
assign mux4_req    = 1'b0;
assign mux4_cs_n   = 1'b0;
assign mux4_ras_n  = 1'b0;
assign mux4_cas_n  = 1'b0;
assign mux4_we_n   = 1'b0;
assign mux4_ba     = 1'b0;
assign mux4_addr   = 1'b0;
assign mux4_dq_out = 1'b0;
assign mux4_dq_oe  = 1'b0;
assign mux4_dqm    = 1'b0;
`endif

//------------------------Body---------------------------
//{{{+++++++++++++++++++++input frame++++++++++++++++++++
assign frame_end   = frame_enable & pg_frame_end;
assign row_end     = frame_enable & pg_row_end;
assign burst_start = frame_enable & pg_burst_start;
assign pixel_en    = frame_enable & pg_pixel_en;

// frame_enable
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        frame_enable <= 1'b0;
    else if (~cfg_input_enable)
        frame_enable <= 1'b0;
    else if (O_sdram_ready && pg_frame_start)
        frame_enable <= 1'b1;
end

// frame_start
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        frame_start <= 1'b0;
    else
        frame_start <= cfg_input_enable & O_sdram_ready & pg_frame_start;
end

//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++frame rate controller++++++++++
assign write_frame_req = pg_frame_start;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++global light+++++++++++++++++++
assign light_adj_coe = {final_light, 7'd0};

assign incr_step = ~incr_light[7:6];

// ext_light
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        ext_light <= 9'd256;
    else if (disp_light == 1'b0)
        ext_light <= 1'b0;
    else
        ext_light <= disp_light + 1'b1;
end

// incr_light
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        time_cnt <= 1'b0;
    else if (I_time_1s_sync)
        begin
        if (time_cnt != 3'd7)
            time_cnt <= time_cnt + 1'b1;
        end
end

always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        incr_light <= 1'b0;
    else if (time_cnt >= 3'd4 && frame_start && ~incr_light[8])
        incr_light <= incr_light + incr_step + 1'b1;
end

// final_light
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        final_light <= 1'b0;
    else if (frame_start) begin
        if (incr_light < ext_light)
            final_light <= incr_light;
        else
            final_light <= ext_light;
    end
end
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++output init++++++++++++++++++++
// init_done
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        init_done <= 1'b0;
    else if (O_sdram_ready & I_bus_init_done & burst_start)
        init_done <= 1'b1;
end

// frame_ready
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        frame_ready <= 1'b0;
    else if (!init_done)
        frame_ready <= 1'b0;
    else if (frame_start)
        frame_ready <= {frame_ready[1:0], 1'b1};
end

//frame_req
assign frame_req  = frame_ready[0] && frame_start;

// output_enable
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        output_enable <= 1'b0;
    else if (frame_ready[1]) //输出使能， 第三帧的
        output_enable <= cfg_output_enable;
end
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++sdram status+++++++++++++++++++
assign O_sdram_ready = sdram_ready_sr[1];

// sdram_ready_sr
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        sdram_ready_sr <= 1'b0;
    else
        sdram_ready_sr <= {sdram_ready_sr[0], sdram_ready_tmp};
end
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++misc+++++++++++++++++++++++++++
assign ext_lock_output  = state[2];  //I_ext_state[2];
assign ext_black_screen = state[3]; //I_ext_state[3];
assign ext_self_sync    = state[4]; //I_ext_state[4];

// win_pos_x
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        win_pos_x <= 1'b0;
    else if (status_pattern_en || status_key_en)
        win_pos_x <= 1'b0;
    else
        win_pos_x <= cfg_win_pos_x;
end

// win_pos_y
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        win_pos_y <= 1'b0;
    else if (status_pattern_en || status_key_en)
        win_pos_y <= 1'b0;
    else
        win_pos_y <= cfg_win_pos_y;
end

assign frame_sync  = (status_pattern_en|frame_lost) ? internal_sync
                   : ext_self_sync ? I_self_sync
                   : I_frame_start;
assign I_fake_frame_start = (status_pattern_en|frame_lost) ? internal_sync
                          : (ext_self_sync ? 1'b0 : fake_frame_start);
assign fps_sync_en = ext_self_sync | cfg_fps_sync_en;

// ms_cnt
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        ms_cnt <= 1'b1;
    else if (I_time_1ms_sync) begin
        if (ms_cnt == SYNC_MS)
            ms_cnt <= 1'b1;
        else
            ms_cnt <= ms_cnt + 1'b1;
    end
end

// internal_sync
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        internal_sync <= 1'b0;
    else if (I_time_1ms_sync && ms_cnt == SYNC_MS)
        internal_sync <= 1'b1;
    else
        internal_sync <= 1'b0;
end
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

endmodule

`default_nettype wire

// vim:set ts=4 sw=4 et fenc=utf-8 fdm=marker:
